/* Copyright (C) 
 * 
 * Disclaim
 * This program is the property of AI Speech Ltd. It shall be communicated to
 * authorized personnel only. It is not to be disclosed outside the group without
 * prior written consent. If you are not sure if you’re authorized to read this
 * program, please contact info@aispeech.com before reading.
 * 
 */

#ifndef ___WXM71___AISPEECH_WTK_UTILS_UTF8_STR__HEADER___
#define ___WXM71___AISPEECH_WTK_UTILS_UTF8_STR__HEADER___


#include "wtk/core/wtk_heap.h"
#include "wtk/core/wtk_array.h"

#ifdef __cplusplus 
extern "C" {
#endif 

struct wtk_strbuf;
typedef struct wtk_utils_ustr wtk_utils_ustr_t;
typedef struct wtk_utils_wrd_range wtk_utils_wrd_range_t;

/**
 * @brief range of sub-word in a raw string 
 */
struct wtk_utils_wrd_range {
    int beg;            ///< start position of word
    int len;            ///< length of word
};


/**
 * @biref a struct used to manipulate utf8 string more conveniently
 */
struct wtk_utils_ustr {
    char *data;
    int len;

    wtk_array_t *arr;   ///< an array of wtk_utils_wrd_range_t*
    wtk_heap_t *heap;
};


/**
 * @brief create and utf8 string from given bytes
 *
 * @param inplace whether make a copy of range bytes, 0=>don't copy, 1=>copy
 *
 * @note if using under inplace model, don't change raw bytes during the life time
 * of create wtk_utils_ustr_t
 */
wtk_utils_ustr_t* wtk_utils_ustr_new(char *data, int len, int inplace);
#define wtk_utils_ustr_new_s(s, inplace) wtk_utils_ustr_new(s, strlen(s), inplace)
#define wtk_utils_ustr_new_str(str, inplace) wtk_utils_ustr_new((str)->data, (str)->len, inplace)

/**
 * @brief delete given ustr
 */
int wtk_utils_ustr_delete(wtk_utils_ustr_t *ustr);


/**
 * @brief get a utf8 character at given position
 */
wtk_string_t wtk_utils_ustr_at(wtk_utils_ustr_t *str, int i);


/**
 * @brief get sub utf8-string, using utf8-character as unit
 */
wtk_string_t wtk_utils_ustr_substr(wtk_utils_ustr_t *str, int fir, int lst);


/**
 * @brief get the number of utf8-character 
 */
#define wtk_utils_ustr_get_num(ustr)  ((ustr)->arr->nslot)

/**
 * @brief test whether all word in a ustr is number
 */
int wtk_utils_ustr_is_num(wtk_utils_ustr_t *ustr);
int wtk_utils_ustr_is_unit(wtk_utils_ustr_t *ustr);
int wtk_utils_ustr_is_num_unit(wtk_utils_ustr_t *ustr);


/**
 * @brief is input unicode character is number, namely,
 * [0-9, 零幺一两二三四五六七八九十壹贰叁肆伍陆柒捌玖拾廿]
 */
int wtk_utils_uchar_is_num(char *data, int len);
#define wtk_utils_uchar_is_num_s(s) wtk_utils_uchar_is_num(s, strlen(s))
#define wtk_utils_uchar_is_num_str(str) wtk_utils_uchar_is_num((str)->data, (str)->len)


/**
 * @brief is input unicode character is number unit, namely:
 * [百千万亿点佰仟]
 */
int wtk_utils_uchar_is_unit(char *data, int len);
#define wtk_utils_uchar_is_unit_s(s) wtk_utils_uchar_is_unit(s, strlen(s))
#define wtk_utils_uchar_is_unit_str(str) wtk_utils_uchar_is_unit((str)->data, (str)->len)


/**
 * @brief translate utf-8 character to number, such as "一" -> "1"
 */
int wtk_utils_uchar_to_num(char *data, int len); 
#define wtk_utils_uchar_to_num_s(s) wtk_utils_uchar_to_num(s, strlen(s))
#define wtk_utils_uchar_to_num_str(str) wtk_utils_uchar_to_num((str)->data, (str)->len)


/**
 * @brief is input unicode character is number or unit
 */
int wtk_utils_uchar_is_num_unit(char *data, int len);
#define wtk_utils_uchar_is_num_unit_s(s) wtk_utils_uchar_is_num_unit(s, strlen(s))
#define wtk_utils_uchar_is_num_unit_str(str) wtk_utils_uchar_is_num_unit((str)->data, (str)->len)


/**
 * @brief test to see whether all words in a input stream is number
 */
int wtk_utils_str_is_num(char *data, int len);
#define wtk_utils_str_is_num_s(s) wtk_utils_str_is_num(s, strlen(s))
#define wtk_utils_str_is_num_str(str) wtk_utils_str_is_num((str)->data, (str)->len)

int wtk_utils_str_is_unit(char *data, int len);
#define wtk_utils_str_is_unit_s(s) wtk_utils_str_is_unit(s, strlen(s))
#define wtk_utils_str_is_unit_str(str) wtk_utils_str_is_unit((str)->data, (str)->len)

int wtk_utils_str_is_num_unit(char *data, int len);
#define wtk_utils_str_is_num_unit_s(s) wtk_utils_str_is_num_unit(s, strlen(s))
#define wtk_utils_str_is_num_unit_str(str) wtk_utils_str_is_num_unit((str)->data, (str)->len)


/**
 * @brief input stream is a word or symbol
 */
int wtk_utils_uchar_is_word(char *data, int len);
#define wtk_utils_uchar_is_word_s(s) wtk_utils_uchar_is_word(s, strlen(s))
#define wtk_utils_uchar_is_word_str(str) wtk_utils_uchar_is_word((str)->data, (str)->len)


/**
 * @brief is this word is an english word
 */
int wtk_utils_uchar_is_eng(char *data, int len);
#define wtk_utils_uchar_is_eng_s(s) wtk_utils_uchar_is_eng(s, strlen(s))
#define wtk_utils_uchar_is_eng_str(str) wtk_utils_uchar_is_eng((str)->data, (str)->len)


/**
 * @brief translate word in string to number, such as "五百八十一号" -> "581号"
 */
int wtk_utils_ustr_trans_num(char *data, int len, struct wtk_strbuf *buf); 
#define wtk_utils_ustr_trans_num_s(s, buf) wtk_utils_ustr_trans_num(s, strlen(s), buf)
#define wtk_utils_ustr_trans_num_str(str, buf) wtk_utils_ustr_trans_num((str)->data, (str)->len, buf)


#ifdef __cplusplus  
};
#endif

#endif
